//
//  UIApplication+LYAdd.m
//  LYDevelopKit
//
//  Created by 李阳 on 2018/6/26.
//

#import "UIApplication+LYAdd.h"
#import <Photos/Photos.h>
#import <AVFoundation/AVFoundation.h>
#import <EventKit/EventKit.h>
#import <Contacts/Contacts.h>
#import <Speech/Speech.h>
#import <HealthKit/HealthKit.h>
#import <MediaPlayer/MediaPlayer.h>
#import <UserNotifications/UserNotifications.h>
#import <CoreBluetooth/CoreBluetooth.h>
#import <CoreLocation/CoreLocation.h>


static NSInteger const PrivacyPermissionTypeLocationDistanceFilter = 10; //`Positioning accuracy` -> 定位精度

@implementation UIApplication (LYAdd)

- (void)accessPrivacyPermissionWithType:(PrivacyPermissionType)type
                             completion:(void(^)(BOOL response,PrivacyPermissionAuthorizationStatus status))completion API_AVAILABLE(ios(10.0))
{
    switch (type) {
        case PrivacyPermissionTypePhoto: {
            [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
                if (status == PHAuthorizationStatusDenied) {
                    completion(NO,PrivacyPermissionAuthorizationStatusDenied);
                } else if (status == PHAuthorizationStatusNotDetermined) {
                    completion(NO,PrivacyPermissionAuthorizationStatusNotDetermined);
                } else if (status == PHAuthorizationStatusRestricted) {
                    completion(NO,PrivacyPermissionAuthorizationStatusRestricted);
                } else if (status == PHAuthorizationStatusAuthorized) {
                    completion(YES,PrivacyPermissionAuthorizationStatusAuthorized);
                }
            }];
        }break;
            
        case PrivacyPermissionTypeCamera: {
            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
                AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
                if (granted) {
                    completion(YES,PrivacyPermissionAuthorizationStatusAuthorized);
                } else {
                    if (status == AVAuthorizationStatusDenied) {
                        completion(NO,PrivacyPermissionAuthorizationStatusDenied);
                    } else if (status == AVAuthorizationStatusNotDetermined) {
                        completion(NO,PrivacyPermissionAuthorizationStatusNotDetermined);
                    } else if (status == AVAuthorizationStatusRestricted) {
                        completion(NO,PrivacyPermissionAuthorizationStatusRestricted);
                    }
                }
            }];
        }break;
            
        case PrivacyPermissionTypeMedia: {
            [MPMediaLibrary requestAuthorization:^(MPMediaLibraryAuthorizationStatus status) {
                if (status == MPMediaLibraryAuthorizationStatusDenied) {
                    completion(NO,PrivacyPermissionAuthorizationStatusDenied);
                } else if (status == MPMediaLibraryAuthorizationStatusNotDetermined) {
                    completion(NO,PrivacyPermissionAuthorizationStatusNotDetermined);
                } else if (status == MPMediaLibraryAuthorizationStatusRestricted) {
                    completion(NO,PrivacyPermissionAuthorizationStatusRestricted);
                } else if (status == MPMediaLibraryAuthorizationStatusAuthorized) {
                    completion(YES,PrivacyPermissionAuthorizationStatusAuthorized);
                }
            }];
        }break;
            
        case PrivacyPermissionTypeMicrophone: {
            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
                AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
                if (granted) {
                    completion(YES,PrivacyPermissionAuthorizationStatusAuthorized);
                } else {
                    if (status == AVAuthorizationStatusDenied) {
                        completion(NO,PrivacyPermissionAuthorizationStatusDenied);
                    } else if (status == AVAuthorizationStatusNotDetermined) {
                        completion(NO,PrivacyPermissionAuthorizationStatusNotDetermined);
                    } else if (status == AVAuthorizationStatusRestricted) {
                        completion(NO,PrivacyPermissionAuthorizationStatusRestricted);
                    }
                }
            }];
        }break;
            
        case PrivacyPermissionTypeLocation: {
            if ([CLLocationManager locationServicesEnabled]) {
                CLLocationManager *locationManager = [[CLLocationManager alloc]init];
                [locationManager requestAlwaysAuthorization];
                [locationManager requestWhenInUseAuthorization];
                locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
                locationManager.distanceFilter = PrivacyPermissionTypeLocationDistanceFilter;
                [locationManager startUpdatingLocation];
            }
            CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
            if (status == kCLAuthorizationStatusAuthorizedAlways) {
                completion(YES,PrivacyPermissionAuthorizationStatusLocationAlways);
            } else if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
                completion(YES,PrivacyPermissionAuthorizationStatusLocationWhenInUse);
            } else if (status == kCLAuthorizationStatusDenied) {
                completion(NO,PrivacyPermissionAuthorizationStatusDenied);
            } else if (status == kCLAuthorizationStatusNotDetermined) {
                completion(NO,PrivacyPermissionAuthorizationStatusNotDetermined);
            } else if (status == kCLAuthorizationStatusRestricted) {
                completion(NO,PrivacyPermissionAuthorizationStatusRestricted);
            }
        }break;
            
        case PrivacyPermissionTypeBluetooth: {
            CBCentralManager *centralManager = [[CBCentralManager alloc] init];
            CBManagerState state = [centralManager state];
            if (state == CBManagerStateUnsupported || state == CBManagerStateUnauthorized || state == CBManagerStateUnknown) {
                completion(NO,PrivacyPermissionAuthorizationStatusDenied);
            } else {
                completion(YES,PrivacyPermissionAuthorizationStatusAuthorized);
            }
        }break;
            
        case PrivacyPermissionTypePushNotification: {
            if (@available(iOS 10.0, *)) {
                UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
                UNAuthorizationOptions types=UNAuthorizationOptionBadge|UNAuthorizationOptionAlert|UNAuthorizationOptionSound;
                [center requestAuthorizationWithOptions:types completionHandler:^(BOOL granted, NSError * _Nullable error) {
                    if (granted) {
                        [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
                            //
                        }];
                    } else {
                        [[UIApplication sharedApplication]openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{UIApplicationOpenURLOptionUniversalLinksOnly:@""} completionHandler:^(BOOL success) { }];
                    }
                }];
            } else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored"-Wdeprecated-declarations"
                [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge categories:nil]];
            }
#pragma clang diagnostic pop
        }break;
            
        case PrivacyPermissionTypeSpeech: {
            [SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) {
                if (status == SFSpeechRecognizerAuthorizationStatusDenied) {
                    completion(NO,PrivacyPermissionAuthorizationStatusDenied);
                } else if (status == SFSpeechRecognizerAuthorizationStatusNotDetermined) {
                    completion(NO,PrivacyPermissionAuthorizationStatusNotDetermined);
                } else if (status == SFSpeechRecognizerAuthorizationStatusRestricted) {
                    completion(NO,PrivacyPermissionAuthorizationStatusRestricted);
                } else if (status == SFSpeechRecognizerAuthorizationStatusAuthorized) {
                    completion(YES,PrivacyPermissionAuthorizationStatusAuthorized);
                }
            }];
        }break;
            
        case PrivacyPermissionTypeEvent: {
            EKEventStore *store = [[EKEventStore alloc] init];
            [store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError * _Nullable error) {
                EKAuthorizationStatus status = [EKEventStore  authorizationStatusForEntityType:EKEntityTypeEvent];
                if (granted) {
                    completion(YES,PrivacyPermissionAuthorizationStatusAuthorized);
                } else {
                    if (status == EKAuthorizationStatusDenied) {
                        completion(NO,PrivacyPermissionAuthorizationStatusDenied);
                    } else if (status == EKAuthorizationStatusNotDetermined) {
                        completion(NO,PrivacyPermissionAuthorizationStatusNotDetermined);
                    } else if (status == EKAuthorizationStatusRestricted) {
                        completion(NO,PrivacyPermissionAuthorizationStatusRestricted);
                    }
                }
            }];
        }break;
            
        case PrivacyPermissionTypeContact: {
            CNContactStore *contactStore = [[CNContactStore alloc] init];
            [contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
                CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
                if (granted) {
                    completion(YES,PrivacyPermissionAuthorizationStatusAuthorized);
                } else {
                    if (status == CNAuthorizationStatusDenied) {
                        completion(NO,PrivacyPermissionAuthorizationStatusDenied);
                    }else if (status == CNAuthorizationStatusRestricted){
                        completion(NO,PrivacyPermissionAuthorizationStatusNotDetermined);
                    }else if (status == CNAuthorizationStatusNotDetermined){
                        completion(NO,PrivacyPermissionAuthorizationStatusRestricted);
                    }
                }
            }];
        }break;
            
        case PrivacyPermissionTypeReminder: {
            EKEventStore *eventStore = [[EKEventStore alloc] init];
            [eventStore requestAccessToEntityType:EKEntityTypeReminder completion:^(BOOL granted, NSError * _Nullable error) {
                EKAuthorizationStatus status = [EKEventStore  authorizationStatusForEntityType:EKEntityTypeEvent];
                if (granted) {
                    completion(YES,PrivacyPermissionAuthorizationStatusAuthorized);
                } else {
                    if (status == EKAuthorizationStatusDenied) {
                        completion(NO,PrivacyPermissionAuthorizationStatusDenied);
                    }else if (status == EKAuthorizationStatusNotDetermined){
                        completion(NO,PrivacyPermissionAuthorizationStatusNotDetermined);
                    }else if (status == EKAuthorizationStatusRestricted){
                        completion(NO,PrivacyPermissionAuthorizationStatusRestricted);
                    }
                }
            }];
        }break;
            
        default:
            break;
    }
}

- (BOOL)openBluetooth
{
    NSString *urlString = nil;
    if ([UIDevice currentDevice].systemVersion.floatValue <= 10)
    {
        urlString = @"prefs:root=Bluetooth";
    }
    else
    {
        urlString = @"App-Prefs:root=Bluetooth";
    }
    NSURL *url = [NSURL URLWithString:urlString];
    return [[UIApplication sharedApplication] openURL:url];
}


#pragma mark - 设置跳转链接
/*
 ios 10前
 蜂窝网络：prefs:root=MOBILE_DATA_SETTINGS_ID
 Wi-Fi：prefs:root=WIFI
 定位服务：prefs:root=LOCATION_SERVICES
 个人热点：prefs:root=INTERNET_TETHERING
 关于本机：prefs:root=General&path=About
 辅助功能：prefs:root=General&path=ACCESSIBILITY
 飞行模式：prefs:root=AIRPLANE_MODE
 锁定：prefs:root=General&path=AUTOLOCK
 亮度：prefs:root=Brightness
 蓝牙：prefs:root=Bluetooth
 时间设置：prefs:root=General&path=DATE_AND_TIME
 FaceTime：prefs:root=FACETIME
 设置：prefs:root=General
 设置 prefs:root=SETTING
 定位服务 prefs:root=LOCATION_SERVICES
 键盘设置：prefs:root=General&path=Keyboard
 iCloud：prefs:root=CASTLE
 iCloud备份：prefs:root=CASTLE&path=STORAGE_AND_BACKUP
 语言：prefs:root=General&path=INTERNATIONAL
 定位：prefs:root=LOCATION_SERVICES
 音乐：prefs:root=MUSIC
 
 ios 10 后
 Wi-Fi: App-Prefs:root=WIFI
 蓝牙: App-Prefs:root=Bluetooth
 蜂窝移动网络: App-Prefs:root=MOBILE_DATA_SETTINGS_ID
 个人热点: App-Prefs:root=INTERNET_TETHERING
 运营商: App-Prefs:root=Carrier
 通知: App-Prefs:root=NOTIFICATIONS_ID
 通用: App-Prefs:root=General
 通用-关于本机: App-Prefs:root=General&path=About
 通用-键盘: App-Prefs:root=General&path=Keyboard
 通用-辅助功能: App-Prefs:root=General&path=ACCESSIBILITY
 通用-语言与地区: App-Prefs:root=General&path=INTERNATIONAL
 通用-还原: App-Prefs:root=Reset
 墙纸: App-Prefs:root=Wallpaper
 Siri: App-Prefs:root=SIRI
 隐私: App-Prefs:root=Privacy
 定位: App-Prefs:root=LOCATION_SERVICES
 Safari: App-Prefs:root=SAFARI
 音乐: App-Prefs:root=MUSIC
 音乐-均衡器: App-Prefs:root=MUSIC&path=com.apple.Music:EQ
 照片与相机: App-Prefs:root=Photos
 FaceTime: App-Prefs:root=FACETIME
 
 */

@end
